package com.projectmanagement.server.service.serviceImpl;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.projectmanagement.server.dao.entity.bo.PageObject;
import com.projectmanagement.server.dao.entity.po.CaseDetail;
import com.projectmanagement.server.dao.entity.po.TaskPlan;
import com.projectmanagement.server.dao.mapper.CaseDetailMapper;
import com.projectmanagement.server.dao.mapper.PlanManageMapper;
import com.projectmanagement.server.service.enums.UserRoleEnum;
import com.projectmanagement.server.service.utils.DateUtil;
import org.apache.commons.lang3.StringUtils;
import org.attoparser.dom.INode;
import org.springframework.stereotype.Service;
import tk.mybatis.mapper.entity.Example;
import tk.mybatis.mapper.util.StringUtil;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @description
 * @author 星空梦语
 * @date 2021/3/9 下午4:08
 */
@Service
public class PlanService {

    @Resource
    private PlanManageMapper planManageMapper;

    @Resource
    private CaseDetailMapper caseDetailMapper;

    private List<CaseDetail> caseDetailList = new ArrayList<>();

    /**
     * @description
     * @author 星空梦语
     * @date 2021/3/9 下午4:08
     */
    public String queryAll(HttpServletRequest request,PageObject pageObject) {
        int offset = (pageObject.getOffset() - 1) * pageObject.getLimit();
        HttpSession session=request.getSession();
        String name=session.getAttribute("name").toString();
        int role= Integer.parseInt(session.getAttribute("role").toString());
        String queryTaskText=pageObject.getData().toString();
        int count=0;
        List<TaskPlan> taskPlanList=new ArrayList<>();
        if(role==UserRoleEnum.RD.getFlag()){
            count= planManageMapper.queryCountByExample(queryTaskText,name);
            taskPlanList = planManageMapper.queryPageData(offset, pageObject.getLimit(), queryTaskText,name);
        }else{
            count= planManageMapper.queryCountByExample(queryTaskText,null);
            taskPlanList = planManageMapper.queryPageData(offset, pageObject.getLimit(), queryTaskText,null);
        }
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("total", count);
        map.put("rows", taskPlanList);
        return JSON.toJSONString(map);
    }


    /**
     * @description
     * @author 星空梦语
     * @date 2021/3/9 下午4:08
     */
    public void editData(String requestData) throws Exception {
        TaskPlan taskPlan = JSON.parseObject(requestData, TaskPlan.class);
        if (taskPlan.getId() == null) {
            taskPlan.setCreateTime(DateUtil.formatToDayByDate3(new Date()));
            planManageMapper.insertSelective(taskPlan);
        } else {
            planManageMapper.updateByPrimaryKey(taskPlan);
        }
    }


    /**
     * @description
     * @author 星空梦语
     * @date 2021/3/9 下午4:08
     */
    public String saveMindCase(PageObject data) {
        try{
            Map map = (Map) data.getData();
            String requestData = JSON.toJSONString(map.get("data"));
            int task = (int) map.get("task");
            JSONObject root = JSON.parseObject(requestData).getJSONObject("root");
            List<Object> list = new ArrayList();
            root.getJSONObject("data").put("parent", "null");
            String template = JSON.parseObject(requestData).get("template").toString();
            String theme = JSON.parseObject(requestData).get("theme").toString();
            root.getJSONObject("data").put("template", template);
            root.getJSONObject("data").put("theme", theme);
            root.getJSONObject("data").put("task", task);
            if(root.getJSONArray("children").size() <=0){
                root.getJSONObject("data").put("hasChildren", false);
            }else{
                root.getJSONObject("data").put("hasChildren", true);
            }
            list.add(root.getJSONObject("data"));
            getChildren(list, root, template, theme, task);
            System.out.println(JSON.toJSONString(list));
            insertMindCase(list);
        }catch (Exception e){
            return "操作异常，异常原因："+e.getMessage();
        }
        return "200";
    }

    /**
     * @description
     * @author 星空梦语
     * @date 2021/3/9 下午4:08
     */
    public void getChildren(List list, JSONObject root, String template, String theme, int task) {
        JSONArray jsonArray = root.getJSONArray("children");
        for (int i = 0; i < jsonArray.size(); i++) {
            JSONObject obj = (JSONObject) jsonArray.get(i);
            obj.getJSONObject("data").put("parent", root.getJSONObject("data").get("id"));
            obj.getJSONObject("data").put("template", template);
            obj.getJSONObject("data").put("theme", theme);
            obj.getJSONObject("data").put("task", task);
            if(obj.getJSONArray("children").size() <=0){
                obj.getJSONObject("data").put("hasChildren", false);
            }else{
                obj.getJSONObject("data").put("hasChildren", true);
            }
            list.add(obj.getJSONObject("data"));
            if (obj.getJSONArray("children").size() > 0) {
                getChildren(list, obj, template, theme, task);
            }
        }
    }


    /**
     * @description
     * @author 星空梦语
     * @date 2021/3/9 下午4:08
     */
    // TODO: 2022/5/22  后续需要增加节点diff判断， 目前是全删全插，需要和库里的数据进行比对，
    //  对比出已经存在需要更新和不存在需要插入的数据分别进行更新和插入操作，不能在进行全部删除
    public void insertMindCase(List<Object> list) {
        List<CaseDetail> caseDetailList = new ArrayList<>();
        for (int i = list.size() - 1; i >= 0; i--) {
            JSONObject obj = (JSONObject) list.get(i);
            CaseDetail caseDetail = new CaseDetail();
            caseDetail.setCaseId(obj.get("id").toString());
            caseDetail.setCaseName(obj.get("text").toString());
            caseDetail.setParentId(obj.get("parent").toString());
            caseDetail.setTemplate(obj.get("template").toString());
            caseDetail.setTheme(obj.get("theme").toString());
            caseDetail.setTaskId((Integer) obj.get("task"));
            caseDetail.setCasePriority(obj.get("priority") == null ? "" : obj.get("priority").toString());
            caseDetail.setCaseProgress(obj.get("progress") == null ? "" : obj.get("progress").toString());
            caseDetail.setHasChildren((Boolean) obj.get("hasChildren"));
            caseDetailList.add(caseDetail);
        }

        Example example = new Example(CaseDetail.class);
        example.createCriteria().andEqualTo("taskId", caseDetailList.get(0).getTaskId());
        caseDetailMapper.deleteByExample(example);
        caseDetailMapper.insertBatch(caseDetailList);
    }


    /**
     * @description
     * @author 星空梦语
     * @date 2021/3/9 下午4:08
     */
    public String queryMindCase(PageObject pageObject) {
        Map map = (Map) pageObject.getData();
        String taskId = map.get("id").toString();
        String root_task = map.get("task").toString();
        Example example = new Example(CaseDetail.class);
        example.createCriteria().andEqualTo("taskId", taskId);
        caseDetailList = caseDetailMapper.selectByExample(example);
        JSONArray jsonArray = query("null");
        if (jsonArray.size() <= 0) {
            JSONObject defaultNode = new JSONObject();
            defaultNode.put("template", "right");
            defaultNode.put("theme", "fresh-blue");
            JSONObject jsonObjectData = new JSONObject();
            jsonObjectData.put("text", root_task);
            jsonObjectData.put("id", getRandomString(12));
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("data", jsonObjectData);
            defaultNode.put("root", jsonObject);
            return JSON.toJSONString(defaultNode);
        }
        JSONObject node = (JSONObject) jsonArray.get(0);
        JSONObject root = new JSONObject();
        root.put("data", node.get("data"));
        root.put("children", node.get("children"));
        node.put("root", root);
        node.remove("data");
        node.remove("children");
        System.out.println(JSON.toJSONString(node));
        return JSON.toJSONString(node);
    }


    /**
     * @description
     * @author 星空梦语
     * @date 2021/3/9 下午4:08
     */
    public JSONArray query(String parentId) {
        List<CaseDetail> dataList = findChildren(parentId);
        JSONArray jsonArray = new JSONArray();
        for (CaseDetail node : dataList) {
            JSONObject jsonObjectNode = new JSONObject();
            if (parentId.equals("null")) {
                jsonObjectNode.put("template", node.getTemplate());
                jsonObjectNode.put("theme", node.getTheme());
                jsonObjectNode.put("version", "1.4.43");
            }
            JSONObject jsonObjectParentData = new JSONObject();
            jsonObjectParentData.put("text", node.getCaseName());
            jsonObjectParentData.put("id", node.getCaseId());
            if(StringUtils.isNotBlank(node.getCasePriority())){
                jsonObjectParentData.put("priority", node.getCasePriority());
            }
            if(StringUtils.isNotBlank(node.getCaseProgress())){
                jsonObjectParentData.put("progress", node.getCaseProgress());
            }
            jsonObjectNode.put("data", jsonObjectParentData);
            JSONArray childs = query(node.getCaseId());
            if (childs.size() > 0) {
                jsonObjectNode.put("children", childs);
            }
            jsonArray.fluentAdd(jsonObjectNode);
        }
        return jsonArray;
    }


    /**
     * @description
     * @author 星空梦语
     * @date 2021/3/9 下午4:08
     */
    public List<CaseDetail> findChildren(String parentId) {
        List<CaseDetail> childList = caseDetailList.stream().filter(caseDetail -> caseDetail.getParentId().equals(parentId)).collect(Collectors.toList());
        return childList;
    }


    /**
     * @description
     * @author 星空梦语
     * @date 2021/3/9 下午4:08
     */
    public static String getRandomString(int length) {
        String str = "zxcvbnmlkjhgfdsaqwertyuiopQWERTYUIOPASDFGHJKLZXCVBNM1234567890";
        Random random = new Random();
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < length; ++i) {
            int number = random.nextInt(62);
            sb.append(str.charAt(number));
        }
        return sb.toString();
    }
}
